package com.xl.utils.rate;

/**
 * @Author:XueH
 * @Description:
 * @Date:Created in 10:11 2023/8/25
 * @Modified By:
 */
public class SpeedLimiter {
    /**
     * 速度上限(KB/s), 0=不限速
     * 也就是1MB
     */
    private int maxRate = 1024;

    /**
     * 下载最大速率
     *
     * @return
     */
    private long getMaxRateBytes() {
        return this.maxRate * 1024;
    }

    /**
     * 最小是10KB/s
     *
     * @return
     */
    private long getLessCountBytes() {
        long lessCountBytes = getMaxRateBytes() / 10;
        if (lessCountBytes < 10240) {
            lessCountBytes = 10240;
        }
        return lessCountBytes;
    }

    public SpeedLimiter(int maxRate) {
        this.setMaxRate(maxRate);
    }

    public synchronized void setMaxRate(int maxRate) {
        this.maxRate = Math.max(maxRate, 0);
    }

    private long totalBytes = 0;
    private long tmpCountBytes = 0;
    private final long lastTime = System.currentTimeMillis();

    /**
     * 计算线程延时
     * sendTime(Ms) = nowTime - lastTime;
     * workTime(Ms) = (totalBytes*1000)/(maxRate*1024)
     * delayTime(Ms) = workTime-sendTime
     **/
    public synchronized void delayNextBytes(int length) {
        if (maxRate <= 0) {
            return;
        }
        totalBytes += length;
        tmpCountBytes += length;
        //未达到指定字节数跳过(最小10kb 10240字节)
        if (tmpCountBytes < getLessCountBytes()) {
            return;
        }
        long nowTime = System.currentTimeMillis();
        long sendTime = nowTime - lastTime;
        //相乘1000（提高精度） 减少因为毫秒问题导致的误差
        long total = totalBytes * 1000;
        long workTime = total / getMaxRateBytes();
        long delayTime = workTime - sendTime;
        if (delayTime > 0) {
            try {
                Thread.sleep(delayTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            tmpCountBytes = 0;
        }
    }

}
